﻿using System;
using System.IO;
using Kotonoha.Server.Xml;
using Kotonoha.Server.Extensions;

namespace Kotonoha.Server.Dictionaries.JMDict {
    [PluggableReader(DictionaryName = "JMDict" , FilePattern = "JMDict")]
    public class JMdictReader : IWordDictionaryReader {
        private JMdict dic;
        private WordEntry word;
        private Meaning mean;
        

        public IWordDictionary read(Stream stream) {
            dic = new JMdict();
            XmlParser parser = new XmlParser(createRootHandler());
            parser.parse(stream);
            GC.Collect();
            return dic;
        }

        private ElementHandler createRootHandler() {
            ParentHandler root = new ParentHandler("JMdict");
            root.Add(createEntryHandler());
            return root;
        }

        private ElementHandler createEntryHandler() {
            ParentHandler entry = new ParentHandler("entry");
            entry.Add(createkHandler());
            entry.Add(createrHandler());
            entry.Add(createSenseHandler());
            entry.OnStart += () => word = new WordEntry();
            entry.OnEnd += () => dic.Add(word);
            return entry;
        }

        private ElementHandler createSenseHandler() {
            ParentHandler sens = new ParentHandler("sense");
            sens.Add(new AttributedHandler("gloss", onGloss));
            sens.OnStart += () => mean = new Meaning();
            sens.OnEnd += () => { if (!mean.IsEmpty()) word.Meanings.Add(mean); };
            return sens;
        }

        private void onGloss(Element e) {
            string lang = e["xml:lang"] ?? "eng";
            if (lang == "eng") {
                mean.Add(e.Content);
            }
        }

        private ElementHandler createrHandler() {
            ParentHandler re = new ParentHandler("r_ele");
            re.Add(new ContentHandler("reb", s => word.Readings.Add(s)));
            return re;
        }

        private ElementHandler createkHandler() {
            ParentHandler ke = new ParentHandler("k_ele");
            ke.Add(new ContentHandler("keb", s => word.Writings.Add(s)));
            return ke;
        }
    }
}
